<?php

	/* SVN FILE: $Id: fnLogin.php 8 2011-03-13 08:32:38Z michele.andreoletti@gmail.com $ */
	
	/**
	 * Project Name : arcadia
	 *
	 * @author $Author: michele.andreoletti@gmail.com $
	 * @version $Revision: 8 $
	 * @lastrevision $Date: 2011-03-13 08:32:38 +0000 (Sun, 13 Mar 2011) $
	 * @filesource $URL: http://arcadia.googlecode.com/svn/trunk/include/fnLogin.php $
	 */

	
	/**
	 * 
	 * fnQueryAuthentication()
	 *
	 * Query MySQL utilizzata per autenticare l'utente.
	 * @param string $sUsername 	campo 'sUsername'
	 * @param string $sPassword 	campo 'sPassword'
	 * @return string 				query MySQL utilizzata per autenticare l'utente
	 *
	 */
	function fnQueryAuthentication ($sUsername, $sPassword='') {		
		$sQuery = "	SELECT `sUsername`, `sPassword`, `sDisplayname`, `iSysop`
					FROM `users`
					WHERE `sUsername`='$sUsername' AND `sType`='user' AND `iEnabled`='1' ";
					if ($sPassword != '') {
						$sQuery .= " AND `sPassword`=(PASSWORD('$sPassword')) ";
					}
		return $sQuery;	
	}	
	
	
	/**
	 * 
	 * fnQueryAuthenticationCoockieDataCheck()
	 *
	 */
	 function fnQueryAuthenticationCoockieDataCheck ($sUsername, $sCode) {
		$sQuery = "SELECT * FROM `users_remember_me`
			WHERE `sUsername` = '$sUsername' AND `sCode` = '$sCode' AND `tsExpiration` >= CURRENT_TIMESTAMP()";			
		return $sQuery;
	}
	
	
	/**
	 * 
	 * fnAuthentication()
	 *
	 * Questa funzione, utilizzando il risultato della query di autenticazione fnQueryAuthentication(),
	 * memorizza nell'array $_SESSION le variabili 'sUsername', 'sPassword', 'iSysop', 'iDebugMsg' e
	 * 'sDisplayname'.
	 *
	 * Esegue inoltre le funzioni fnGetAssociatedGroups(), fnAppAccessLvl() e fnUpdateLog().
	 *
	 */	 
	function fnAuthentication ($rResult, $bRememberMe) {

		if (!isset($_SESSION)) { session_start(); }
		
		$aRow = mysql_fetch_array($rResult);
		
		fnDeleteExpiredAuthenticationCodes($aRow['sUsername']);
		
		// informazioni comuni: sUsername, sPassword, 'iSysop', sDisplayname
		fnSaveSessionValue($aRow['sUsername'], 'sUsername');
		fnSaveSessionValue($aRow['sPassword'], 'sPassword');
		fnSaveSessionValue($aRow['iSysop'], 'iSysop');
		
		global $iDEBUG_MSG;	// FIXME
		fnSaveSessionValue($iDEBUG_MSG, 'iDebugMsg');
		
		if (trim($aRow['sDisplayname']) != '') {
			fnSaveSessionValue($aRow['sDisplayname'], 'sDisplayname');
	    } else {
	    	fnSaveSessionValue($aRow['sUsername'], 'sDisplayname');
	    }
	    
	    // $bRememberMe
	    if ($bRememberMe) {
	   		fnRememberMe($aRow['sUsername']);
	    }
	    
	    // fnAppAccessLvl >> user
	    fnAppAccessLvl($aRow['sUsername'], 'user');
	    
	    // fnGetAssociatedGroups
		$sGroups = fnGetAssociatedGroups($aRow['sUsername']);
	    foreach ($sGroups as $sGroup) {
	    	// fnAppAccessLvl >> group
			fnAppAccessLvl($sGroup, 'group');
	    }
	   
		fnUpdateLog('LOGIN',0,'','S');
	
	}

	/**
	 *
	 * fnRememberMe()
	 *
	 */
	function fnRememberMe ($sUsername) {
		global $sSUITE_NAME, $sAPP;
		
		$sCode = fnRandomString();
		$sExpires = time()+(3600*24*5); /* coockie will expire in 5 days */
	
		if (fnAuthenticationCoockieDataCheck()) {
			// se è già presente un coockie con un codice di autenticazione valido, lo elimino dal database
			fnDeleteCode(fnReadAuthenticationCoockie('sUsername'), fnReadAuthenticationCoockie('sCode'));								
		}
		// salvo il nuovo coockie
		setcookie($sSUITE_NAME, $sUsername."|".$sCode, $sExpires);
		// salvo il nuovo codice di autenticazione nel database
		fnSaveCode($sUsername, $sCode, $sExpires);	
	}
	
	
	/**
	 *
	 * fnAuthenticationWithCoockie()
	 *
	 */
	function fnAuthenticationWithCoockie () {
		global $sSUITE_NAME, $sAPP;
		
		if (fnAuthenticationCoockieDataCheck()) {
			$sQuery = fnQueryAuthentication(fnReadAuthenticationCoockie('sUsername'));
			$rResult = custom_mysql_query($sQuery, 'fnQueryAuthentication()');
			// Autenticazione avvenuta con successo (ovvero: l'utente è attivo)
			if (mysql_num_rows($rResult) == 1) {
				fnAuthentication($rResult, false);
				fnRememberMe(fnReadAuthenticationCoockie('sUsername'));			
			}
		}
	}
	
	
	/**
	 *
	 * fnAuthenticationCoockieDataCheck
	 *
	 */	
	function fnAuthenticationCoockieDataCheck () {
		global $sSUITE_NAME, $sAPP;
		
		if (isset($_COOKIE[$sSUITE_NAME]) && !empty($_COOKIE[$sSUITE_NAME])) {
			$sUsername = fnReadAuthenticationCoockie('sUsername');
			$sCode = fnReadAuthenticationCoockie('sCode');
			$sQuery = fnQueryAuthenticationCoockieDataCheck($sUsername, $sCode);
			$rResult = custom_mysql_query($sQuery, 'fnQueryAuthenticationCoockieDataCheck()');
			if (mysql_num_rows($rResult) == 1) {
				return true;
			}
		}
		return false;	
	} 
	
	
	/**
	 *
	 * fnReadAuthenticationCoockie()
	 *
	 */		
	function fnReadAuthenticationCoockie ($sWhat='sUsername'){
		global $sSUITE_NAME, $sAPP;
		
		if (isset($_COOKIE[$sSUITE_NAME]) && !empty($_COOKIE[$sSUITE_NAME])) {
			list($sUsername, $sCode) = explode ("|", $_COOKIE[$sSUITE_NAME]);
			if (isset($$sWhat)) {
				return $$sWhat;
			}
		}
	}
	
	
	/**
	 *
	 * fnDeleteExpiredAuthenticationCodes()
	 *
	 */		
	function fnDeleteExpiredAuthenticationCodes($sUsername) {
		$sQuery = fnQueryDeleteExpiredAuthenticationCodes($sUsername);
		$rResult = custom_mysql_query($sQuery, 'fnQueryDeleteExpiredAuthenticationCodes()');
	}
	
	
	/**
	 *
	 * fnQueryDeleteExpiredAuthenticationCodes()
	 *
	 */		
	function fnQueryDeleteExpiredAuthenticationCodes($sUsername) {
		$sQuery = "DELETE FROM `users_remember_me`
					WHERE `sUsername` = '$sUsername' AND `tsExpiration` < CURRENT_TIMESTAMP()";
		return $sQuery;	
	}
	
	
	/**
	 *
	 * fnSaveCode()
	 *
	 */		
	function fnSaveCode ($sUsername, $sCode, $tsExpiration) {	
		$sQuery = fnQuerySaveCode($sUsername, $sCode, $tsExpiration);
		$rResult = custom_mysql_query($sQuery, 'fnQuerySaveCode()');
	}
	
	
	/**
	 *
	 * fnQuerySaveCode()
	 *
	 */		
	function fnQuerySaveCode ($sUsername, $sCode, $tsExpiration) {	
		$sQuery = "INSERT INTO `users_remember_me` 
					(`sUsername`, `sCode`, `tsExpiration`)
					VALUES
					('$sUsername', '$sCode', '".date('Y-m-d H:i:s', $tsExpiration)."')";
		return $sQuery;	
	}
	
	
	/**
	 *
	 * fnDeleteCode()
	 *
	 */				
	function fnDeleteCode ($sUsername, $sCode) {	
		$sQuery = fnQueryDeleteCode($sUsername, $sCode);	
		$rResult = custom_mysql_query($sQuery, 'fnQueryDeleteCode()');
	}
	
	
	/**
	 *
	 * fnQueryDeleteCode()
	 *
	 */	
	function fnQueryDeleteCode ($sUsername, $sCode) {
		$sQuery = "DELETE FROM `users_remember_me` WHERE `sUsername` = '$sUsername' AND `sCode` = '$sCode'";
		return $sQuery;	
	}	
	
	
	/**
	 *
	 * fnRandomString()
	 *
	 */	
	function fnRandomString ($iLength=64) {	
		$sChars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; // la stringa generata sarò composta dai caratteri contenuti in questa stringa
		$iMax = strlen($sChars)-1;
		$sCode = '';
		for ($i=0; $i<$iLength; $i++) {
			$sCode .= $sChars{mt_rand(0, $iMax)};
		}
		return $sCode;
	}


	/**
	 * 
	 * Crea un array con i nomi dei gruppi in cui l'utente è inserito.
	 * In caso l'utente non sia inserito in nessun gruppo restituisce un array vuoto.
	 * @param	string	$sUsername
	 * @return	array
	 */
	function fnGetAssociatedGroups($sUsername)  {
		global $sSUITE_NAME, $sAPP;
		
		$aGroups = array();
		$aData = fnGetDataFromQuery(fnQueryGetAssociatedGroups($sUsername));
		if (!empty($aData)) {
			foreach ($aData as $aRow) {
				$aGroups[] = $aRow['sGroup'];
			}
		}
		return $aGroups;
	}
	
	function fnQueryGetAssociatedGroups ($sUser) {
		$sQuery = "SELECT `users_groups_lnk`.`sGroup`, `users`.`sDisplayname`
				FROM `users_groups_lnk`
				LEFT OUTER JOIN `users` ON `users`.`sUsername` = `users_groups_lnk`.`sGroup`
			 	WHERE `users_groups_lnk`.`sUser` = '$sUser'
			 	ORDER BY `users_groups_lnk`.`sGroup`";	
		return $sQuery;
	}

	
	/**
	 * 
	 * Determina i permessi di accesso di un utente alle applicazioni.
	 * Sulla base dei risultati della query memorizza in $_SESSION tutti i permessi di accesso dell'
	 * utente all'applicazione ed ai suoi elementi (sTable, sViewItemLink, sTab, sField).
	 * 
	 * @param string $sUsername		nome utente oppure nome del gruppo
	 * @param string $sType			'user', 'group'
	 */
	function fnAppAccessLvl($sUsername, $sType) {
	
		if (!isset($_SESSION)) { session_start(); }
		
		// Nel caso i permessi fossero già presenti (i primi ad essere memorizzati sono quelli relativi
		// all'utente, dopodichè vengono memorizzati tutti quelli relativi ai gruppi di cui l'utente fa parte)
		// viene salvato il livello di accesso più elevato.
		// Solo nel caso in cui sia presente il livello di accesso "-1" (ovvero: accesso negato), viene 
		// sempre e comunque salvato il livello di accesso "-1"
		
		$sQuery = fnQueryAppAccessLvl($sUsername, $sType);
		$rResult = custom_mysql_query($sQuery, 'fnQueryAppAccessLvl()');
		
		if (mysql_num_rows($rResult) > 0) {
			while ($aRow = mysql_fetch_array($rResult)) {
				if (fnReadSessionValue(array('sTable' => $aRow['sTable'], 'sViewItemLink' => $aRow['sViewItemLink'], 'sTab' => $aRow['sTab'], 'sField' => $aRow['sField']), 'AccessLvl', $aRow['sApp'], $aRow['sWhat']) != -1) {
					
					if ($aRow['iAccessLvl'] != -1) {
						$iAccessLvl = max(fnReadSessionValue(array('sTable' => $aRow['sTable'], 'sViewItemLink' => $aRow['sViewItemLink'], 'sTab' => $aRow['sTab'], 'sField' => $aRow['sField']), 'AccessLvl', $aRow['sApp'], $aRow['sWhat']), $aRow['iAccessLvl']);
					} else {
						$iAccessLvl	= $aRow['iAccessLvl'];
					}
					
					fnSaveSessionValue($iAccessLvl, array('sTable' => $aRow['sTable'], 'sViewItemLink' => $aRow['sViewItemLink'], 'sTab' => $aRow['sTab'], 'sField' => $aRow['sField']), 'AccessLvl', $aRow['sApp'], $aRow['sWhat']);
				
				}
			}
		}

	}


	/**
	 *
	 * fnQueryAppAccessLvl
	 *
	 */
	function fnQueryAppAccessLvl ($sUsername, $sType) {
		$sQuery = "	SELECT `sUsername`, `sType`, `sApp`, `sTable`, `sViewItemLink`, `sTab`, `sField`, `sWhat`, `iAccessLvl`
					FROM `users_access_lvl`
					WHERE `sUsername`='$sUsername' AND `sType` = '$sType'";
		return $sQuery;		
	}
?>